import libtcodpy as libtcod

class ConsoleError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

class Console(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self._con = libtcod.console_new(width, height)
        self.root = False


    def blit(self, x, y, width, height, dst, x_dst, y_dst, foreground_alpha=1.0, background_alpha=1.0):
        if hasattr(dst, 'blit'):
            libtcod.console_blit(self._con, x, y, width, height, dst.console, x_dst, y_dst, 
                                 foreground_alpha, background_alpha)
        elif not dst:
            libtcod.console_blit(self._con, x, y, width, height, 0, x_dst, y_dst, 
                                 foreground_alpha, background_alpha)
        else:
            raise ConsoleError("Cannot blit to %r" % repr(dst))

    def set_background_color(self, color):
        libtcod.console_set_background_color(self._con, color)
    def set_foreground_color(self, color):
        libtcod.console_set_foreground_color(self._con, color)
    def clear(self):
        libtcod.console_clear(self._con)

    def putchar(self, x, y, char, flag):
        libtcod.console_put_char(self._con, x, y, char, flag)
    def putchar_ex(self, x, y, char, fore, back):
        libtcod.console_put_char_ex(self._con, x, y, char, fore, back)
    def set_back(self, x, y, color, flag):
        libtcod.console_set_back(self._con, x, y, color, flag)
    def set_fore(self, x, y, color):
        libtcod.console_set_fore(self._con, x, y, color)
    def set_char(self, x, y, char):
        libtcod.console_set_char(self._con, x, y, char)

    def print_left(self, x, y, flag, fmt):
        libtcod.console_print_left(self._con, x, y, flag, fmt)
    def print_right(self, x, y, flag, fmt):
        libtcod.console_print_right(self._con, x, y, flag, fmt)
    def print_center(self, x, y, flag, fmt):
        libtcod.console_print_center(self._con, x, y, flag, fmt)

    def print_left_rect(self, x, y, width, height, flag, fmt):
        return libtcod.console_print_left_rect(self._con, x, y, width, height, flag, fmt)
    def height_left_rect(self, x, y, width, height, fmt):
        return libtcod.console_height_left_rect(self._con, x, y, width, height, fmt)
    def print_right_rect(self, x, y, width, height, flag, fmt):
        return libtcod.console_print_right_rect(self._con, x, y, width, height, flag, fmt)
    def height_right_rect(self, x, y, width, height, fmt):
        return libtcod.console_height_right_rect(self._con, x, y, width, height, fmt)
    def print_center_rect(self, x, y, width, height, flag, fmt):
        return libtcod.console_print_center_rect(self._con, x, y, width, height, flag, fmt)
    def height_center_rect(self, x, y, width, height, fmt):
        return libtcod.console_height_center_rect(self._con, x, y, width, height, fmt)

    def rect(self, x, y, width, height, clear, flag):
        libtcod.console_rect(self._con, x, y, width, height, clear, flag)
    def hline(self, x, y, length, flag):
        libtcod.console_hline(self._con, x, y, length) #XXX:, flag)
    def vline(self, x, y, length, flag):
        libtcod.console_vline(self._con, x, y, length, flag)
    def frame(self, x, y, width, height, clear, flag, fmt=None):
        libtcod.console_print_frame(self._con, x, y, width, height, clear, flag, fmt)

    def get_background_color(self):
        return libtcod.get_background_color(self._con)
    def get_foreground_color(self):
        return libtcod.get_foreground_color(self._con)
    def get_back(self, x, y):
        return libtcod.get_back(self._con)
    def get_fore(self, x, y):
        return libtcod.get_fore(self._con, x, y)
    def get_char(self, x, y):
        return libtcod.get_char(self._con, x, y)

    @property
    def console(self):
        return self._con

    @property
    def background(self):
        return libtcod.console_get_background_color(self._con)
    @background.setter
    def background(self, color):
        libtcod.console_set_background_color(self._con, color)

    @property
    def foreground(self):
        return libtcod.console_get_foreground_color(self._con)
    @foreground.setter
    def foreground(self, color):
        libtcod.console_set_foreground_color(self._con, color)



class RootConsole(Console):
    def __init__(self, width, height, title='', fullscreen=False):
        self.width = width
        self.height = height
        self._title = title

        libtcod.console_init_root(self.width, self.height, self._title, fullscreen)

        self._con = 0
        self.root = True

    def flush(self):
        libtcod.console_flush()

    def is_fullscreen(self):
        return self.fullscreen
    def set_fullscreen(self, full):
        libtcod.console_set_fullscreen(full)
    def is_window_closed(self):
        return libtcod.console_is_window_closed()

    def set_window_title(self, title):
        self.title = title  # Calls @title.setter

    def credits(self):
        libtcod.console_credits()
    def credits_render(self, x, y, alpha):
        return libtcod.console_credits_render(x, y, alpha)
    def credits_reset(self):
        libtcod.console_credits_reset()

    def wait_for_keypress(self, flush):
        return libtcod.console_wait_for_keypress(flush)
    def check_for_keypress(self, flags=libtcod.KEY_RELEASED):
        return libtcod.console_check_for_keypress(flags)
    def is_key_pressed(self, key):
        return libtcod.console_is_key_pressed(key)
    def key_pressed(self, key):
        return libtcod.console_is_key_pressed(key)

    def set_keyboard_repeat(self, initial_delay, interval):
        libtcod.console_set_keyboard_repeat(initial_delay, interval)
    def disable_keyboard_repeat(self):
        libtcod.console_disable_keyboard_repeat()

    def print_fps(self):
        fmt = "FPS: %3d" % libtcod.sys_get_fps()
        self.print_right(self.width-1, self.height-1, libtcod.BKGND_SET, fmt)

    @property
    def title(self):
        return self._title
    @title.setter
    def title(self, title):
        self._title = title
        libtcod.console_set_window_title(self._title)

    @property
    def closed(self):
        return libtcod.console_is_window_closed()
    @property
    def open(self):
        return not libtcod.console_is_window_closed()

    @property
    def fullscreen(self):
        return libtcod.console_is_fullscreen()
    @fullscreen.setter
    def fullscreen(self, full):
        libtcod.console_set_fullscreen(full)



def set_fade(fade, fadingColor):
    libtcod.console_set_fade(fade, fadingColor)
def get_fade():
    libtcod.console_get_fade()
def get_fading_color():
    libtcod.console_get_fading_color()


if __name__ == '__main__':
    from pprint import pprint

    libtcod.console_set_custom_font('fonts/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    root = RootConsole(80, 40, 'Title')
    root.background = libtcod.red
    root.foreground = libtcod.green
    root.rect(0, 0, 80, 40, True, libtcod.BKGND_SET)
    root.print_center(40, 0, libtcod.BKGND_NONE, "TEST")



    con1 = Console(20, 20)
    con1.background = libtcod.yellow
    con1.foreground = libtcod.blue
    con1.frame(0, 0, 20, 20, True, libtcod.BKGND_NONE, 'con1')
    con1.blit(0, 0, 20, 20, root, 5, 5, foreground_alpha=1.0, background_alpha=0.5)
    root.flush()

    con2 = Console(20, 20)
    con2.background = libtcod.green
    con2.foreground = libtcod.white
    con2.frame(0, 0, 20, 20, True, libtcod.BKGND_NONE, 'con2')
    con2.blit(0, 0, 20, 20, root, -5, 35)
    root.flush()


    print "Press and key..."
    root.wait_for_keypress(True)

